#include <iostream>
#include <cstring>
using namespace std;

const int N = 6010; //人的编号最多是6000

int h[N], e[N], ne[N], idx = 0; //邻接表，这里提前开的e空间只有N的大小是因为除了根节点，每个人稳定只有一条边
int n;                          //获取人员数量
int happy[N];                   //获取每个人的快乐值
int f[N][2];                    //状态表示方程
int a, b;                       //获取关系
int p[N];                       //记录上司是谁
int r = 1;                      //记录根节点

void add(int a, int b) //领接表的添加，a是b的上司
{
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx++;
    return;
}

void dfs(int k) //计算k的f[k][0]和f[k][1]，当然，计算他的条件至少得计算他下面的所有的0和1
{
    f[k][0] = 0;                      //如果我没来，那么我基本就没办法提供快乐值
    f[k][1] = happy[k];               //如果我来了，那么我就能提供我的那一份
    for (int i = h[k]; ~i; i = ne[i]) //这里的~i就是对i逐步取非，因为补码的原因，-1的逐步取非就是0
    {
        int j = e[i];                     //将存储的值取出来
        dfs(j);                           //计算出他的全部
        f[k][0] += max(f[j][0], f[j][1]); //上司没来嘛，所以下属可以选择来还是本来
        f[k][1] += f[j][0];               //上司来了嘛，下属只有不来了
    }
    return;
}

int main()
{
    freopen("cin.txt", "r", stdin);
    cin >> n;
    for (int i = 1; i <= n; ++i)
        cin >> happy[i];
    memset(h, -1, sizeof h); //初始化所有表头
    memset(p, -1, sizeof p); //初始化上司关系记录表
    for (int i = 1; i < n; ++i)
    {
        cin >> b >> a; //注意题目描述，后面是前面的上司
        add(a, b);
        p[b] = a;
    }
    while (p[r] != -1)
        ++r;                       //为了找到根结点
    dfs(r);                        //将f[r][0]和f[r][1]都算出来
    cout << max(f[r][1], f[r][0]); //只需要对比根结点来不来即可
    return 0;
}